home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Programming / LEDA / source / src / graph / _g_random.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  12.1 KB  |  544 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  _g_random.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15. #include <LEDA/graph.h>
  16. #include <LEDA/ugraph.h>
  17.  
  18.  
  19. void random_graph(graph& G, int n, int m)
  20. { /* random graph with n nodes and m edges */ 
  21.  
  22.  int i;
  23.  node* V = new node[n];
  24.  G.clear();
  25.  for(i=0;i<n;i++) V[i] = G.new_node();
  26.  
  27.  while (m--) G.new_edge(V[random(0,n-1)],V[random(0,n-1)]);
  28.  
  29. /*
  30.  int deg = m/n;
  31.  int r = m%n;
  32.  int k;
  33.  for(i=0;i<n;i++)
  34.    for(k=0;k<deg;k++)
  35.       G.new_edge(V[i],V[random(0,n-1)]);
  36.  while (r--) G.new_edge(V[random(0,n-1)],V[random(0,n-1)]);
  37. */
  38.  
  39. }
  40.  
  41. void random_ugraph(ugraph& G, int n, int m)
  42. { int i;
  43.  node* V = new node[n];
  44.  G.clear();
  45.  for(i=0;i<n;i++) V[i] = G.new_node();
  46.  while (m--) G.new_edge(V[random(0,n-1)],V[random(0,n-1)]);
  47. }
  48.  
  49. void random_bigraph(graph& G,int n1,int n2,int m,list<node>& A,list<node>& B)
  50. {
  51.    int  d = m/n1; 
  52.    int  r = m%n1; 
  53.  
  54.    node* AV = new node[n1];
  55.    node* BV = new node[n2];
  56.  
  57.    A.clear();
  58.    B.clear();
  59.    G.clear();
  60.  
  61.    for(int a = 0; a < n1; a++)  A.append(AV[a] = G.new_node());
  62.    for(int b = 0; b < n2; b++)  B.append(BV[b] = G.new_node());
  63.  
  64.    node v;
  65.    int i;
  66.  
  67.    forall(v,A)
  68.      for(i=0;i<d;i++)
  69.        G.new_edge(v,BV[random(0,n2-1)]);
  70.  
  71.    while (r--) G.new_edge(AV[random(0,n1-1)], BV[random(0,n2-1)]);
  72.  
  73. }
  74.  
  75.  
  76.  
  77.  
  78. //------------------------------------------------------------------------------
  79. // random planar graph
  80. //------------------------------------------------------------------------------
  81.  
  82. #include <LEDA/sortseq.h>
  83. #include <LEDA/prio.h>
  84. #include <math.h>
  85.  
  86.  
  87. #define EPS  0.00001
  88. #define EPS2 0.0000000001
  89.  
  90. class POINT;
  91. class SEGMENT;
  92. typedef POINT* point;
  93. typedef SEGMENT* segment;
  94.  
  95. enum point_type {Intersection=0,Rightend=1,Leftend=2}; 
  96.  
  97. class POINT
  98. {
  99.   friend class SEGMENT;
  100.  
  101.   segment seg;
  102.   int     kind;
  103.   double  x;
  104.   double  y;
  105.  
  106.   public:
  107.  
  108.   POINT(double a,double b)  
  109.   { 
  110.     x=a; y=b; seg=0; kind=Intersection;
  111.    }
  112.  
  113.  
  114.   LEDA_MEMORY(POINT);
  115.  
  116.   friend double    get_x(point);
  117.   friend double    get_y(point);
  118.   friend int       get_kind(point);
  119.   friend segment get_seg(point);
  120.  
  121.   friend bool intersection(segment, segment, point&);
  122. };
  123.  
  124. inline double    get_x(point p)    { return p->x; }
  125. inline double    get_y(point p)    { return p->y; }
  126. inline int       get_kind(point p) { return p->kind; }
  127. inline segment get_seg(point p)  { return p->seg; }   
  128.  
  129.  
  130.  
  131. static int compare(point& p1,point& p2)
  132. { if (p1==p2) return 0;
  133.  
  134.   double diffx = get_x(p1) - get_x(p2);
  135.   if (diffx >  EPS2 ) return  1;
  136.   if (diffx < -EPS2 ) return -1;
  137.  
  138.   int    diffk = get_kind(p1)-get_kind(p2);
  139.   if (diffk != 0) return diffk;
  140.  
  141.   double diffy = get_y(p1) - get_y(p2);
  142.   if (diffy >  EPS2 ) return  1;
  143.   if (diffy < -EPS2 ) return -1;
  144.  
  145.   return 0;
  146.  
  147. }
  148.  
  149.  
  150. class SEGMENT
  151. {
  152.   point startpoint;
  153.   point endpoint;
  154.   double  slope;
  155.   double  yshift;
  156.   node  left_node;
  157.   int   orient;
  158.   int   color;
  159.   int   name;
  160.  
  161.  
  162.   public:
  163.  
  164.   SEGMENT(point, point,int,int);     
  165.  
  166.  ~SEGMENT() { delete startpoint; delete endpoint; }     
  167.  
  168.   LEDA_MEMORY(SEGMENT);
  169.  
  170.   friend point get_startpoint(segment);
  171.   friend point get_endpoint(segment);
  172.   friend double get_slope(segment);
  173.   friend double get_yshift(segment);
  174.   friend int  get_orient(segment);
  175.   friend int  get_color(segment);
  176.   friend int  get_name(segment);
  177.   friend node get_left_node(segment);
  178.   friend void set_left_node(segment, node);
  179.  
  180.   friend bool intersection(segment, segment, point&);
  181. };
  182.  
  183.  
  184. inline point get_startpoint(segment seg)     { return seg->startpoint; }
  185. inline point get_endpoint(segment seg)       { return seg->endpoint; }
  186. inline double get_slope(segment seg)           { return seg->slope; }
  187. inline double get_yshift(segment seg)          { return seg->yshift; }
  188. inline int  get_orient(segment seg)            { return seg->orient; }
  189. inline int  get_color(segment seg)             { return seg->color; }
  190. inline int  get_name(segment seg)              { return seg->name; }
  191. inline node get_left_node(segment seg)         { return seg->left_node; }
  192. inline void set_left_node(segment seg, node v) { seg->left_node = v; }
  193.  
  194.  
  195.  
  196. SEGMENT::SEGMENT(point p1,point p2,int c, int n)    
  197.   {
  198.     left_node  = nil;
  199.     color      = c;
  200.     name       = n;
  201.  
  202.     if (compare(p1,p2) < 0)
  203.      { startpoint = p1; 
  204.        endpoint = p2; 
  205.        orient = 0;
  206.       }
  207.     else
  208.      { startpoint = p2; 
  209.        endpoint = p1; 
  210.        orient = 1;
  211.       }
  212.  
  213.     startpoint->kind = Leftend; 
  214.     endpoint->kind = Rightend; 
  215.     startpoint->seg = this; 
  216.     endpoint->seg = this;
  217.  
  218.     if (endpoint->x != startpoint->x)
  219.     {
  220.       slope = (endpoint->y - startpoint->y)/(endpoint->x - startpoint->x);
  221.       yshift = startpoint->y - slope * startpoint->x;
  222.  
  223.       startpoint->x -= EPS;
  224.       startpoint->y -= EPS * slope;
  225.       endpoint->x += EPS;
  226.       endpoint->y += EPS * slope;
  227.     }
  228.     else //vertical segment
  229.     { startpoint->y -= EPS;
  230.       endpoint->y   += EPS;
  231.      }
  232.   }
  233.  
  234.  
  235. static double x_sweep;
  236. static double y_sweep;
  237.  
  238.  
  239. static int compare(segment& s1,segment& s2)
  240. {
  241.   double y1 = get_slope(s1)*x_sweep+get_yshift(s1);
  242.   double y2 = get_slope(s2)*x_sweep+get_yshift(s2);
  243.  
  244.   double diff = y1-y2;
  245.   if (diff >  EPS2 ) return  1;
  246.   if (diff < -EPS2 ) return -1;
  247.  
  248.   if (get_slope(s1) == get_slope(s2)) 
  249.         return compare(get_x(get_startpoint(s1)), get_x(get_startpoint(s2)));
  250.  
  251.   if (y1 <= y_sweep+EPS2)
  252.         return compare(get_slope(s1),get_slope(s2));
  253.   else
  254.         return compare(get_slope(s2),get_slope(s1));
  255.  
  256. }
  257.  
  258.  
  259.  
  260. static priority_queue<seq_item,point> X_structure;
  261.  
  262. static sortseq<segment,pq_item> Y_structure;
  263.  
  264.  
  265. bool intersection(segment seg1,segment seg2, point& inter)
  266. {
  267.   if (seg1->slope == seg2->slope)
  268.     return false;
  269.   else
  270.   { 
  271.     double cx = (seg2->yshift - seg1->yshift) / (seg1->slope - seg2->slope);
  272.  
  273.     if (cx <= x_sweep) return false;
  274.  
  275.     if (seg1->startpoint->x > cx || seg2->startpoint->x > cx ||
  276.         seg1->endpoint->x < cx || seg2->endpoint->x < cx ) return false;
  277.  
  278.     inter = new POINT(cx,seg1->slope * cx + seg1->yshift);
  279.  
  280.     return true;
  281.   }
  282. }
  283.  
  284.  
  285.  
  286. inline pq_item Xinsert(seq_item i, point p) 
  287. { return X_structure.insert(i,p); }
  288.  
  289.  
  290. inline point Xdelete(pq_item i) 
  291. { point p = X_structure.inf(i);
  292.   X_structure.del_item(i);
  293.   return p;
  294.  }
  295.  
  296.  
  297. void random_planar_graph(graph& G, int m)
  298. { node_array<double> xcoord;
  299.   node_array<double> ycoord;
  300.   random_planar_graph(G,xcoord,ycoord,m);
  301.  }
  302.  
  303. void random_planar_graph(graph& G, node_array<double>& xcoord,
  304.                                    node_array<double>& ycoord, int n)
  305. {
  306.   point    p,inter;
  307.   segment  seg, l,lsit,lpred,lsucc,lpredpred;
  308.   pq_item  pqit,pxmin;
  309.   seq_item sitmin,sit,sitpred,sitsucc,sitpredpred;
  310.  
  311.   int MAX_X = 1000;
  312.   int MAX_Y = 1000;
  313.  
  314.   int N = int(2.5*sqrt(n)); // number of random segments
  315.  
  316.   xcoord.init(G,n,0);
  317.   ycoord.init(G,n,0);
  318.  
  319.  
  320.   int count=1;
  321.  
  322.   //initialization of the X-structure
  323.  
  324.   for (int i = 0; i < N; i++)
  325.    { point p = new POINT(random(0,MAX_X/3), random(0,MAX_Y));
  326.      point q = new POINT(random(2*MAX_X/3,MAX_X), random(0,MAX_Y));
  327.      seg = new SEGMENT(p,q,0,count++);
  328.      Xinsert(nil,get_startpoint(seg));
  329.    }
  330.  
  331.   count = 0;
  332.  
  333.   x_sweep = -MAXINT;
  334.   y_sweep = -MAXINT;
  335.  
  336.  
  337.   while( !X_structure.empty() && G.number_of_nodes() < n)
  338.   {
  339.     pxmin = X_structure.find_min();
  340.     p = X_structure.inf(pxmin);
  341.  
  342.     sitmin = X_structure.key(pxmin);
  343.  
  344.     Xdelete(pxmin);
  345.  
  346.  
  347.  
  348.     if (sitmin == nil) //left endpoint
  349.     { 
  350.       l = get_seg(p); 
  351.  
  352.       x_sweep = get_x(p);
  353.       y_sweep = get_y(p);
  354.  
  355.  
  356.       sit = Y_structure.insert(l,nil);
  357.  
  358.       Xinsert(sit,get_endpoint(l));
  359.  
  360.       sitpred = Y_structure.pred(sit);
  361.       sitsucc = Y_structure.succ(sit);
  362.  
  363.       if (sitpred != nil) 
  364.       { if ((pqit = Y_structure.inf(sitpred)) != nil)
  365.           delete Xdelete(pqit);
  366.  
  367.         lpred = Y_structure.key(sitpred);
  368.  
  369.         Y_structure.change_inf(sitpred,nil);
  370.  
  371.         if (intersection(lpred,l,inter))
  372.             Y_structure.change_inf(sitpred,Xinsert(sitpred,inter));
  373.       }
  374.  
  375.  
  376.       if (sitsucc != nil)
  377.       { lsucc = Y_structure.key(sitsucc);
  378.         if (intersection(lsucc,l,inter))
  379.            Y_structure.change_inf(sit,Xinsert(sit,inter));
  380.       }
  381.  
  382.     }
  383.     else if (get_kind(p) == Rightend)
  384.          //right endpoint
  385.          { 
  386.            x_sweep = get_x(p);
  387.            y_sweep = get_y(p);
  388.  
  389.            sit = sitmin;
  390.  
  391.            sitpred = Y_structure.pred(sit);
  392.            sitsucc = Y_structure.succ(sit);
  393.  
  394.            segment seg = Y_structure.key(sit);
  395.  
  396.            Y_structure.del_item(sit);
  397.  
  398.            delete seg;
  399.  
  400.            if((sitpred != nil)&&(sitsucc != nil))
  401.            {
  402.              lpred = Y_structure.key(sitpred);
  403.              lsucc = Y_structure.key(sitsucc);
  404.              if (intersection(lsucc,lpred,inter))
  405.                 Y_structure.change_inf(sitpred,Xinsert(sitpred,inter));
  406.            }
  407.          }
  408.          else // intersection point p
  409.          { 
  410.            node w = G.new_node();
  411.  
  412.            xcoord[w] = get_x(p);
  413.            ycoord[w] = get_y(p);
  414.  
  415.            count++;
  416.  
  417.            /* Let L = list of all lines intersecting in p 
  418.  
  419.               we compute sit     = L.head();
  420.               and        sitpred = L.tail();
  421.  
  422.               by scanning the Y_structure in both directions 
  423.               starting at sitmin;
  424.  
  425.            */
  426.  
  427.            /* search for sitpred upwards from sitmin: */
  428.  
  429.            Y_structure.change_inf(sitmin,nil);
  430.  
  431.            sitpred = Y_structure.succ(sitmin);
  432.  
  433.  
  434.            while ((pqit=Y_structure.inf(sitpred)) != nil)
  435.            { point q = X_structure.inf(pqit);
  436.              if (compare(p,q) != 0) break; 
  437.              X_structure.del_item(pqit);
  438.              Y_structure.change_inf(sitpred,nil);
  439.              sitpred = Y_structure.succ(sitpred);
  440.             }
  441.  
  442.  
  443.            /* search for sit downwards from sitmin: */
  444.  
  445.            sit = sitmin;
  446.  
  447.            seq_item sit1;
  448.            
  449.            while ((sit1=Y_structure.pred(sit)) != nil)
  450.            { pqit = Y_structure.inf(sit1);
  451.              if (pqit == nil) break;
  452.              point q = X_structure.inf(pqit);
  453.              if (compare(p,q) != 0) break; 
  454.              X_structure.del_item(pqit);
  455.              Y_structure.change_inf(sit1,nil);
  456.              sit = sit1;
  457.             }
  458.  
  459.  
  460.  
  461.            // insert edges to p for all segments in sit, ..., sitpred into G
  462.            // and set left node to w 
  463.  
  464.            lsit = Y_structure.key(sitpred);
  465.  
  466.            node v = get_left_node(lsit);
  467.            if (v!=nil) G.new_edge(v,w);
  468.            set_left_node(lsit,w);
  469.  
  470.            for(sit1=sit; sit1!=sitpred; sit1 = Y_structure.succ(sit1))
  471.            { lsit = Y_structure.key(sit1);
  472.  
  473.              v = get_left_node(lsit);
  474.              if (v!=nil) G.new_edge(v,w);
  475.              set_left_node(lsit,w);
  476.             }
  477.  
  478.            lsit = Y_structure.key(sit);
  479.            lpred=Y_structure.key(sitpred);
  480.            sitpredpred = Y_structure.pred(sit);
  481.            sitsucc=Y_structure.succ(sitpred);
  482.  
  483.  
  484.            if (sitpredpred != nil)
  485.             { 
  486.               lpredpred=Y_structure.key(sitpredpred);
  487.  
  488.               if ((pqit = Y_structure.inf(sitpredpred)) != nil)
  489.                 delete Xdelete(pqit);
  490.  
  491.               Y_structure.change_inf(sitpredpred,nil);
  492.  
  493.  
  494.               if (intersection(lpred,lpredpred,inter))
  495.                 Y_structure.change_inf(sitpredpred,
  496.                                        Xinsert(sitpredpred,inter));
  497.              }
  498.  
  499.  
  500.            if (sitsucc != nil)
  501.             {
  502.               lsucc=Y_structure.key(sitsucc);
  503.  
  504.               if ((pqit = Y_structure.inf(sitpred)) != nil)
  505.                 delete Xdelete(pqit);
  506.                  
  507.               Y_structure.change_inf(sitpred,nil);
  508.  
  509.               if (intersection(lsucc,lsit,inter))
  510.                   Y_structure.change_inf(sit,Xinsert(sit,inter));
  511.              }
  512.  
  513.  
  514. // reverse the subsequence sit, ... ,sitpred  in the Y_structure
  515.  
  516.            x_sweep = get_x(p);
  517.            y_sweep = get_y(p);
  518.  
  519.            Y_structure.reverse_items(sit,sitpred);
  520.  
  521.           delete p;
  522.  
  523.          } // intersection
  524.  
  525.   }
  526.  
  527.   X_structure.clear();
  528.   Y_structure.clear();
  529.  
  530.  
  531.  
  532.   // normalize x and y coordinates 
  533.  
  534.   node v;
  535.   forall_nodes(v,G) 
  536.   { xcoord[v] /= (x_sweep + MAX_X/12);
  537.     ycoord[v] /= MAX_Y;
  538.    }
  539.  
  540. }
  541.  
  542.  
  543.